package com.mjk.service.system;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.mjk.common.util.NumberUtil;
import com.mjk.common.util.TreeUtil;
import com.mjk.constant.AdminCommonConstant;
import com.mjk.constant.CommonConstants;
import com.mjk.model.info.User;
import com.mjk.model.system.Element;
import com.mjk.model.system.Menu;
import com.mjk.service.info.UserService;
import com.mjk.vo.IntactUser;
import com.mjk.vo.MenuTree;
import com.mjk.vo.PermissionInfo;

@Service
public class PermissionService {

	@Autowired
	private UserService userService;
	@Autowired
	private MenuService menuService;
	@Autowired
	private ElementService elementService;
	
	public IntactUser getUserInfo(String id){
		User user = userService.selectByPrimaryKey(NumberUtil.parseInteger(id));
		IntactUser intactUser = new IntactUser();
		BeanUtils.copyProperties(user, intactUser);
		List<PermissionInfo> permissionInfos = this.getPermissionByUsername(user.getUsername());
		Stream<PermissionInfo> menus = permissionInfos.parallelStream().filter((permission) -> {
            return permission.getType().equals(CommonConstants.RESOURCE_TYPE_MENU);
        });
		intactUser.setMenus(menus.collect(Collectors.toList()));
        Stream<PermissionInfo> elements = permissionInfos.parallelStream().filter((permission) -> {
            return !permission.getType().equals(CommonConstants.RESOURCE_TYPE_MENU);
        });
        intactUser.setElements(elements.collect(Collectors.toList()));
        return intactUser;
	}
	
	public List<PermissionInfo> getPermissionByUsername(String username) {
        User user = userService.getUserByUsername(username);
        List<Menu> menus = menuService.getUserAuthorityMenuByUserId(user.getId());
        List<PermissionInfo> result = new ArrayList<PermissionInfo>();
        PermissionInfo info = null;
        menu2permission(menus, result);
        List<Element> elements = elementService.getAuthorityElementByUserId(user.getId() + "");
        element2permission(result, elements);
        return result;
    }
	
	
	private void element2permission(List<PermissionInfo> result, List<Element> elements) {
	    PermissionInfo info;
	    for (Element element : elements) {
	        info = new PermissionInfo();
	        info.setCode(element.getCode());
	        info.setType(element.getType());
	        info.setUri(element.getUri());
	        info.setMethod(element.getMethod());
	        info.setName(element.getName());
	        info.setMenu(element.getMenuId());
	        result.add(info);
	    }
    }
	
	private void menu2permission(List<Menu> menus, List<PermissionInfo> result) {
        PermissionInfo info;
        for (Menu menu : menus) {
            if (StringUtils.isBlank(menu.getHref())) {
                menu.setHref("/" + menu.getCode());
            }
            info = new PermissionInfo();
            info.setCode(menu.getCode());
            info.setType(AdminCommonConstant.RESOURCE_TYPE_MENU);
            info.setName(AdminCommonConstant.RESOURCE_ACTION_VISIT);
            String uri = menu.getHref();
            if (!uri.startsWith("/")) {
                uri = "/" + uri;
            }
            info.setUri(uri);
            info.setMethod(AdminCommonConstant.RESOURCE_REQUEST_METHOD_GET);
            result.add(info
            );
            info.setMenu(menu.getTitle());
        }
    }
	
	public List<MenuTree> getMenusByUsername(String id) throws Exception {
		User user = userService.selectByPrimaryKey(NumberUtil.parseInteger(id));
        List<Menu> menus = menuService.getUserAuthorityMenuByUserId(user.getId());
        return getMenuTree(menus,AdminCommonConstant.ROOT);
    }
	
	private List<MenuTree> getMenuTree(List<Menu> menus, int root) {
        List<MenuTree> trees = new ArrayList<MenuTree>();
        MenuTree node = null;
        for (Menu menu : menus) {
            node = new MenuTree();
            BeanUtils.copyProperties(menu, node);
            trees.add(node);
        }
        return TreeUtil.bulid(trees, root);
    }
}
